﻿using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace HostsManager.Model
{
    public class Hosts
    {
        private const String DefaultSectionName = "Global";
        private const String DefaultConfigurationName = "Global";

        public Dictionary<String, Section> Sections
        {
            get { return sections; }
        }
        private Dictionary<String, Section> sections;

        public Section DefaultSection
        {
            get { return sections[DefaultSectionName]; }
        }

        public Configuration DefaultConfiguration
        {
            get 
            {
                return DefaultSection.GetConfiguration(DefaultConfigurationName);
            }
        }

        private Dictionary<string, Configuration> configurationIndex;

        /// <summary>
        /// Default constructor
        /// </summary>
        public Hosts()
        {
            // Create a collection for holding all sections
            sections = new Dictionary<String, Section>();

            // Create index for direct access to configurations
            configurationIndex = new Dictionary<string, Configuration>();

            // Create a default section/configuration (anything outside any section will be placed here)
            Section defaultSection = new Section(DefaultSectionName, true);
            Configuration defaultConfiguration = new Configuration(DefaultConfigurationName, true);
            defaultSection.AddConfiguration(defaultConfiguration);
            sections.Add(DefaultSectionName, defaultSection);
        }

        /// <summary>
        /// Adds a section if it does not exist
        /// </summary>
        /// <param name="sectionName"></param>
        /// <param name="enabled"></param>
        // public Section AddSection(String sectionName, bool enabled)
        public Section AddSection(Section section)
        {
            if (!sections.Keys.Contains(section.Name))
                sections.Add(section.Name, section);

            return section;
        }

        /// <summary>
        /// Removes a section from hosts
        /// </summary>
        /// <param name="section">The section to be removed</param>
        internal void RemoveSection(Section section)
        {
            if (sections.Keys.Contains(section.Name))
                sections.Remove(section.Name);
        }

        /// <summary>
        /// Adds a configuration if it does not exist
        /// </summary>
        /// <param name="sectionName"></param>
        /// <param name="configurationName"></param>
        /// <param name="enabled"></param>
        public Configuration AddConfiguration(String sectionName, String configurationName, String enabled)
        {
            Configuration configuration = null;
            Section section = null;

            bool exists = sections.TryGetValue(sectionName, out section);
            if (exists && section != null)
            {
                configuration = section.GetConfiguration(configurationName);
                if (configuration == null)
                {
                    bool isEnabled = (enabled.ToLower() == "on");

                    // If the configuration to add is active, all others must be disabled
                    if (isEnabled)
                        section.DisableAllConfigurations();

                    configuration = new Configuration(configurationName, isEnabled);
                    section.AddConfiguration(configuration);
                    configurationIndex.Add(configuration.InternalId, configuration);
                }
            }

            return configuration;
        }

        public string GetUnusedSectionName()
        {
            int counter = 0;
            string name;

            do
            {
                ++counter;
                name = "section" + counter.ToString().PadLeft(2, '0');
            } while (this.Sections.Keys.Contains(name));

            return name;
        }
    }
}
